package com.panopset.sf;

import java.awt.Color;
import java.awt.LayoutManager;

import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;
import javax.swing.text.JTextComponent;

import com.deprecated.patch.LookAndFeel;

/**
 * Swing component factory.
 * 
 * @author Karl Dinwiddie.
 * 
 */
public final class ComponentFactory {

	private FontManager fm = FontManager.getInstance();

	/**
	 * @param layout
	 *            Layout.
	 * @return Panel with a white background.
	 */
	public JPanel createPanel(final LayoutManager layout) {
		JPanel p = new JPanel(layout);
		p.setBackground(Color.WHITE);
		return p;
	}

	/**
	 * @param layout
	 *            Layout.
	 * @param title
	 *            Title.
	 * @param tip
	 *            Tool tip text.
	 * @return Panel with a white background.
	 */
	public JPanel createTitledPanel(final LayoutManager layout,
			final String title, final String tip) {
		JPanel p = createTitledPanel(layout, title);
		p.setToolTipText(tip);
		return p;
	}

	/**
	 * @param layout
	 *            Layout.
	 * @param title
	 *            Title.
	 * @return Panel with a white background.
	 */
	public JPanel createTitledPanel(final LayoutManager layout,
			final String title) {
		JPanel p = createPanel(layout);
		p.setBorder(createTitledBorder(title));
		return p;
	}

	/**
	 * @param w
	 *            Windoc.
	 * @param columns
	 *            Field width.
	 * @param tip
	 *            Tool tip text.
	 * @param dft
	 *            Default.
	 * @param key
	 *            Persistent store key. If the key is empty, a key will be
	 *            generated based on the stack trace. If the key is null, there
	 *            will be no registration.
	 * @return Text field.
	 */
	public JTextField createTextField(final Windoc w, final int columns,
			final String tip, final String dft, final String key) {
		final JTextField tf = createTextField(w, dft, key);
		tf.setColumns(columns);
		tf.setToolTipText(tip);
		return tf;
	}

	/**
	 * @param w
	 *            Windoc.
	 * @param dft
	 *            Default.
	 * @param key
	 *            Persistent store key. If the key is empty, a key will be
	 *            generated based on the stack trace. If the key is null, there
	 *            will be no registration.
	 * @return Text field.
	 */
	public JTextField createTextField(final Windoc w, final String dft,

	final String key) {
		final JTextField tf = new JTextField();
		registerTextComponent(w, tf, dft, key);
		return tf;
	}

	/**
	 * @param w
	 *            Windoc.
	 * @param key
	 *            Persistent store key. If the key is empty, a key will be
	 *            generated based on the stack trace. If the key is null, there
	 *            will be no registration.
	 * @return Text field.
	 */
	public JTextField createKeyedTextField(final Windoc w, final String key) {
		return createTextField(w, "", key);
	}

	/**
	 * 
	 * @return Tabbed pane.
	 */
	public JTabbedPane createTabbedPane() {
		JTabbedPane jtp = new JTabbedPane();
		fm.register(jtp, FontManager.FontType.plainArial);
		jtp.setBackground(Color.WHITE);
		return jtp;
	}

	/**
	 * @param w
	 *            Windoc
	 * @param c
	 *            Component.
	 * @param dft
	 *            Default value.
	 * @param key
	 *            Storage key. Can be null, for fields that are not persistent.
	 * @return c Component.
	 */
	public JTextComponent registerTextComponent(final Windoc w,
			final JTextComponent c, final String dft, final String key) {
		if (w != null & key != null) {
			w.registerGrounding(new Grounding() {

				@Override
				public void setValue(final String value) {
					c.setText(value);
				}

				@Override
				public String getValue() {
					return c.getText();
				}
			}, dft, key);
		}
		fm.register(c, FontManager.FontType.monospace);
		c.setBackground(Color.WHITE);
		return c;
	}

	/**
	 * @param title
	 *            Title.
	 * @return Titled border.
	 */
	public TitledBorder createTitledBorder(final String title) {
		TitledBorder tb = new TitledBorder(title);
		fm.register(tb, FontManager.FontType.borderTitle);
		tb.setTitleColor(LookAndFeel.Colors.FG_COLOR.getColor());
		return tb;
	}

	/**
	 * @param w
	 *            Windoc
	 * @param columns
	 *            Field width.
	 * @param title
	 *            Title.
	 * @param tip
	 *            Tool tip text.
	 * @param dft
	 *            Default.
	 * @param key
	 *            Persistent store key. If the key is empty, a key will be
	 *            generated based on the stack trace. If the key is null, there
	 *            will be no registration.
	 * @return Field with a titled border.
	 */
	public JTextField createTitledField(final Windoc w, final int columns,
			final String title, final String tip, final String dft,
			final String key) {
		JTextField rtn = createTextField(w, dft, key);
		rtn.setColumns(columns);
		rtn.setBorder(createTitledBorder(title));
		rtn.setToolTipText(tip);
		return rtn;
	}

	/**
	 * @param w
	 *            Windoc.
	 * @param columns
	 *            Field width.
	 * @param title
	 *            Title.
	 * @param tip
	 *            Tool tip text.
	 * @param key
	 *            Persistent store key. If the key is empty, a key will be
	 *            generated based on the stack trace. If the key is null, there
	 *            will be no registration.
	 * @return Field with a titled border.
	 */
	public JTextField createTitledField(final Windoc w, final int columns,
			final String title, final String tip, final String key) {
		return createTitledField(w, columns, title, tip, "", key);
	}

	/**
	 * @param w
	 *            Windoc.
	 * @param title
	 *            Title.
	 * @param tip
	 *            Tool tip text. Can be null.
	 * @param dft
	 *            Default.
	 * @param key
	 *            Persistent store key. If the key is empty, a key will be
	 *            generated based on the stack trace. If the key is null, there
	 *            will be no registration.
	 * @return Text area with a titled border.
	 */
	public TitledTextArea createTitledTextArea(final Windoc w,
			final String title,

			final String tip, final String dft, final String key) {
		return new TitledTextArea(w, title, tip, dft, key);
	}

	/**
	 * @param w
	 *            Windoc.
	 * @param title
	 *            Title.
	 * @param tip
	 *            Tool tip text. Can be null.
	 * @param key
	 *            Persistent store key. If the key is empty, a key will be
	 *            generated based on the stack trace. If the key is null, there
	 *            will be no registration.
	 * @return Text area with a titled border.
	 */
	public TitledTextArea createTitledTextArea(final Windoc w,
			final String title,

			final String tip, final String key) {
		return new TitledTextArea(w, title, tip, key);
	}

	/**
	 * @param w
	 *            Windoc.
	 * @param columns
	 *            Columns.
	 * @param tip
	 *            Tool tip text.
	 * @param dft
	 *            Default.
	 * @param key
	 *            Persistent store key. If the key is empty, a key will be
	 *            generated based on the stack trace. If the key is null, there
	 *            will be no registration.
	 * @return Password field
	 */
	public JPasswordField createPasswordField(final Windoc w,
			final int columns, final String tip, final String dft,
			final String key) {
		JPasswordField jpf = new JPasswordField();
		jpf.setToolTipText(tip);
		registerTextComponent(w, jpf, dft, key);
		return jpf;
	}

	/**
	 * @param w
	 *            Windoc.
	 * @param columns
	 *            Columns.
	 * @param title
	 *            Title.
	 * @param tip
	 *            Tool tip text.
	 * 
	 * @param key
	 *            Persistent store key. If the key is empty, a key will be
	 *            generated based on the stack trace. If the key is null, there
	 *            will be no registration.
	 * @return Password field.
	 */
	public JPasswordField createTitledPasswordField(final Windoc w,
			final int columns, final String title, final String tip,
			final String key) {
		JPasswordField jpf = createPasswordField(w, columns, tip, "", key);
		jpf.setBorder(createTitledBorder(title));
		return jpf;
	}

	/**
	 * A passive component is a button or menu that does not need to save state.
	 * 
	 * @param c
	 *            JComponent to register with FontManager and set to theme
	 *            colors.
	 */
	public void registerPassiveComponent(final JComponent c) {
		fm.register(c, FontManager.FontType.boldArial);
	}

	/**
	 * @param w
	 *            Windoc.
	 * @param name
	 *            Name.
	 * @param tip
	 *            Tip.
	 * @param dft
	 *            Default value.
	 * @param key
	 *            Persistent store key. If the key is empty, a key will be
	 *            generated based on the stack trace. If the key is null, there
	 *            will be no registration.
	 * @return JCheckBox that remembers its state.
	 */
	public JCheckBox createGroundedCheckBox(final Windoc w, final String name,

	final String tip, final boolean dft, final String key) {
		final JCheckBox rtn = new JCheckBox(name);
		rtn.setBackground(Color.WHITE);
		rtn.setToolTipText(tip);
		registerPassiveComponent(rtn);
		w.registerGrounding(new Grounding() {
			@Override
			public void setValue(final String s) {
				rtn.setSelected(Boolean.parseBoolean(s));
			}

			@Override
			public String getValue() {
				return "" + rtn.isSelected();
			}
		}, "" + dft, key);
		return rtn;
	}

	public JComboBox createGroundedComboBox(final Windoc w,
			final String name, final String tip, final String dft,
			final String key, final String[] selections) {
		final JComboBox rtn = new JComboBox(selections);
		rtn.setToolTipText(tip);
		rtn.setName(name);
		rtn.setSelectedItem(dft);
		registerPassiveComponent(rtn);
		w.registerGrounding(new Grounding() {
			@Override
			public void setValue(final String s) {
				rtn.setSelectedItem(s);
			}

			@Override
			public String getValue() {
				return rtn.getSelectedItem().toString();
			}
		}, "" + dft, key);
		return rtn;
	}
}
